package cs423.loadBalancer.core;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

import android.widget.Toast;

public class Util {
    static int period = 50;
    
    /**
     * Get CPU information by parsing the /proc/stat file
     * @return the overall cpu usage
     */
	public static float getCpu() {

		BufferedReader br = getFileReader();
       
        int[] firstJiffies = new int[2]; // first one is total, second one is first three
        int[] secondJiffies = new int[2];
        getJiffies(firstJiffies, br);
      
        
        closeFile(br);      
        
		try {
			Thread.sleep(period);//sleep 
		} catch (InterruptedException e) {
			System.out.println("Sleep exception in getCpu function");
			e.printStackTrace();
		}
		
		br = getFileReader();
		getJiffies(secondJiffies,br);
		
		closeFile(br); 
		
		
		int totalOverPeriod = secondJiffies[0] - firstJiffies[0];
		int workOverPeriod = secondJiffies[1] - firstJiffies[1];
		System.out.println("secondJiffies[0] is  " + secondJiffies[0] + "secondJiffies[1] is " + secondJiffies[1]);
		System.out.println("firstJiffies[0] is " + firstJiffies[0] + "firstJiffies[1] is " + firstJiffies[1]);
		System.out.println("total is " + totalOverPeriod + "work is " + workOverPeriod);

		float cpuPercentage = ((float)workOverPeriod / totalOverPeriod ) * 100;
		System.out.println("cpuPercentage is " + cpuPercentage);

		return cpuPercentage;
	}

	//closes the file
	private static void closeFile(BufferedReader br) {
		  try {
				br.close();
			} catch (IOException e1) {
				System.out.println("close file exception");
				e1.printStackTrace();
			}
	}

	private static BufferedReader getFileReader() {
		BufferedReader br = null;
		try {
			br = new BufferedReader( new FileReader("/proc/stat"));
		} catch (FileNotFoundException e) {
			System.out.println("cannot read /proc/stat");
			e.printStackTrace();
		}
        return br;
	}

	/***
	 * Read the first line of /proc/stat and get the jiffies info
	 * @param jiffies
	 * @param br
	 */
	private static void getJiffies(int[] jiffies, BufferedReader br) {
		String cpuFirstLine = null;
        String[] cpuInfo = null;
		try {
			if ((cpuFirstLine = br.readLine()) != null) {
				// Toast.makeText(this, x, Toast.LENGTH_LONG).show();
				cpuInfo = cpuFirstLine.split("\\s+");
				int totalJiffie = getTotalJiffies(cpuInfo);
				int workJiffie = getWorkJiffies(cpuInfo);
				jiffies[0]	 = totalJiffie;
				jiffies[1] = workJiffie;				
			} else {
				System.out.println("Cannot read the first line");
			}
		} catch (IOException e) {
			System.out.println("Read the first line exception");
			e.printStackTrace();
		}
		
	}

	private static int getWorkJiffies(String[] cpuInfo) {
		int firstThree = 0;
		for(int i =1; i<=3  ; ++i ) {
			firstThree += Integer.parseInt(cpuInfo[i]);
		}
		return firstThree;
	}

	private static int getTotalJiffies(String[] cpuInfo) {
		int total = 0;
		for(int i =1; i< cpuInfo.length ; ++i ) {
			total += Integer.parseInt(cpuInfo[i]);
		}
		return total;
	}

	/**
	 * Convert the byte data into double 2D array
	 * @param input
	 * @param width
	 * @return
	 */
	public static double[][] convertByteToDouble2D(byte[] input, int width) {

		ByteBuffer buf = ByteBuffer.wrap(input);
		int total_length = input.length / 8;
		int height = total_length / width;
		double[][] output = new double[height][width];
		for (int i = 0; i < height; i++)
			for (int j = 0; j < width; j++){
				output[i][j] = buf.getDouble((i * width + j) * 8);
				//System.out.println(output[i][j]);
			}
		return output;
	}
	
	public static List<Integer> cutData(double[][]input, int interval, String kind){
		
		List<Integer> output = new ArrayList<Integer>();
				
		int pos=0;
		while(pos<input[0].length)
		{
			if(kind=="CLIENT")
			{
				for(int i=0; i<input.length/2; i++)
				{
					output.add(new Integer(i*input[0].length + pos));	
					//System.out.println("Height: "+i+";  Width: "+pos);
				}
				pos+=interval;
			}
			else
			{
				for(int i=input.length/2; i<input.length; i++)
				{
					output.add(new Integer(i*input[0].length + pos));	
					//System.out.println("Height: "+i+";  Width: "+pos);
				}
				pos+=interval;
			}
		}

		return output;
	}

}
